package com.fanrui.code.chess.mahjong.round;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import com.fanrui.code.chess.mahjong.AbstractMahjongTable;
import com.fanrui.code.chess.mahjong.Mahjong;
import com.fanrui.code.chess.mahjong.MahjongGamer;
import com.fanrui.code.chess.mahjong.StandingsRound;
import com.fanrui.code.mahjong.util.MahjongCardUtil;
import com.fanrui.code.util.logger.Stdout;
import com.fanrui.proto.cmd.NotifyCanOperationCard;
import com.fanrui.proto.cmd.Operation;
import com.fanrui.proto.cmd.ResPlayerOperation.Result;

/**
 * @ClassName: MahjongQiangGangHuRound
 * @Description: 抢杠回合
 * @author bear
 */
public class MahjongQiangGangHuRound extends MahjongRound {
	private final static List<Operation> CANRESPONSE = Arrays.asList(Operation.GUO, Operation.BOOM);
	private final Collection<Long> waitNum;
	private MahjongOperationResponse scoure;

	public MahjongQiangGangHuRound(MahjongOperationResponse scoure, Long currentId, AbstractMahjongTable<?> table) {
		super(currentId, CANRESPONSE, table);
		waitNum = table.getSurvivalPlayers(currentId);
		this.scoure = scoure;
		filterCantOperation();
	}

	public Mahjong getOperationCard() {
		return scoure.getCard();
	}

	@Override
	public MahjongOperationResponse getScoreResponse() {
		return scoure;
	}

	@Override
	public boolean isAoutoNext() {
		return false;
	}

	@Override
	public StandingsRound toStandingsRound() {
		return null;
	}

	@Override
	public Result addResponse(MahjongOperationResponse response) {
		Result result = canOperationType(response);
		if (result != Result.Success) {
			return result;
		}
		MahjongGamer gamer = table.getGamerByPlayerID(response.getOperationId());
		Mahjong operationCard = response.getCard();
		if(response.getType() != Operation.GUO) {
			if (gamer == null || operationCard == null) {
				return Result.ParameterInvalid;
			}
		}
		if (response.getType() == Operation.GUO) {
			gamer.setGuoShouHuAuto(response.getCard());
		}
		if (response.getType() == Operation.BOOM) {
			if (!MahjongCardUtil.getInstance().checkHu(operationCard, gamer, table.getGameRules())) {
				Stdout.GET().info("检测到不能胡牌:" + gamer.getPlayerID());
				return Result.CantHu;
			}
			// 是否为过手胡
			if (gamer.getGuoShouHu() != null) {
				if (gamer.getMult(response.getCard()) <= gamer.getGuoShouHu()) {
					Stdout.GET().info("过小胡大不能胡：" + gamer.getGuoShouHu() + "--" + gamer.getPlayerID());
					return Result.GuoShouHu;
				}
			}
		}

		// 判断是否能够加入到操作中
		addResponseToList(response);
		return result;
	}

	@Override
	public Object doResponse() {

		if (playerResponse.size() < getCanResponseList().size()) {
			return null;
		}

		boolean none = true;
		for (MahjongOperationResponse response : playerResponse) {
			if (response.getType() != Operation.GUO) {
				none = false;
			}
		}
		if (isDoResponse) {
			return null;
		}
		isDoResponse = true;
		if (none) {
			// 都不要 下家摸牌
			table.setCurrentRound(new MahjongGangRound(scoure, scoure.getOperationId(), table, scoure, 1));
		} else {
			filterResponse();
			for (MahjongOperationResponse response : playerResponse) {
				// 找到一个合适的响应并执行
				MahjongRound round = RoundUtil.getInstance().createQiangGangRound(this, response, table);
				if (response.getType() == Operation.BOOM) {
					round.before();
//					break;
				} else {
					table.setCurrentRound(round);
				}
			}
			table.setHaveHu(true);
			table.addRound(this);
			table.startRound(currentId);
		}
		return null;
	}

	@Override
	public void before() {
		if (waitNum.isEmpty()) {
			doResponse();
		}else {
			for (Long id : waitNum) {
				if(scoure != null) {
					MahjongGamer gamer = table.getGamerByPlayerID(id);
					if(gamer != null) {
						NotifyCanOperationCard.Builder notify = NotifyCanOperationCard.newBuilder();
						notify.addOperation(Operation.BOOM);
						notify.setOperationMahjong(scoure.getCard().toCardCmd());
						gamer.send(notify.build());
					}
				}
			}
		}
	}

	@Override
	public Collection<Long> getCanResponseList() {
		return waitNum;
	}

	/**
	 * 过滤掉当前不能执行的操作
	 * 
	 * @return Collection<MahjongOperationResponse>
	 */
	public Collection<MahjongOperationResponse> filterResponse() {
		
		// 排序
		Collections.sort(playerResponse);
		// 胡>杠>碰>过
		// 根据规则 筛选 可以执行的操作
		Iterator<MahjongOperationResponse> iterator = playerResponse.iterator();

		Operation priority = null;
		// 其他麻将只能有一种类型
		while (iterator.hasNext()) {
			MahjongOperationResponse response = iterator.next();
			if (priority == null) {
				priority = response.getType();
			} else if (response.getType().getNumber() < priority.getNumber()) {
				iterator.remove();
			}
		}

		return null;
	}

	/**
	 * 过滤掉不能操作的玩家 void
	 */
	public void filterCantOperation() {
		if (waitNum != null && !waitNum.isEmpty()) {
			Iterator<Long> iterator = waitNum.iterator();
			while (iterator.hasNext()) {
				MahjongGamer gamer = table.getGamerByPlayerID(iterator.next());
//				if (gamer != null && !gamer.canOperationCard(scoure.getCard())) { // 这里改成了 机器人和托管的玩家不能抢杠胡牌 
				if (gamer != null && (!gamer.checkHu(scoure.getCard()) || gamer.getHosting())) { 
					iterator.remove();
				}
			}
		}
	}

	@Override
	public String getInfo() {
		return String.format("牌桌ID:%s --- 玩家:%s 抢杠回合", table.getID(), currentId);
	}
}